package com.tjc.project.schduler;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tjc.project.constant.PreSchedulerConstant;
import com.tjc.project.model.entity.InterfaceInfo;
import com.tjc.project.service.InterfaceInfoService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

import static com.tjc.project.constant.PreSchedulerConstant.PRESCHEDULER_LOCK_NAME;
import static com.tjc.project.constant.PreSchedulerConstant.PRESCHEDULER_NAME;

/**
 * @ClassName PreScheduler
 * @Author tjc
 * <p>
 * 这个类为了防止用户打开的时候加载过慢将第一页的接口数据使用缓存进行加速
 **/
@Component
public class PreScheduler {
    private static final Logger log = LoggerFactory.getLogger(PreScheduler.class);
    // 得到redis操作对象
    @Resource
    RedisTemplate<String, Object> redisTemplate;

    @Resource
    InterfaceInfoService interfaceInfoService;

    @Resource
    RedissonClient redissonClient;

    /**
     * 实现方法进行定时任务，cron脚本
     * 1. 实现分布式在每天零点进行网页预热的功能
     */
    @Scheduled(cron = "0 0 0 * * *")
    public void DoScheduler() {
        // 1. 定义要去redis中取得的锁
        RLock lock = redissonClient.getLock(PRESCHEDULER_LOCK_NAME);
        try {
            // 2. 尝试获得锁
            boolean getLock = lock.tryLock(0, -1, TimeUnit.SECONDS);

            if (getLock) {
                // 1. 从数据库中查询到第一页的接口数据
                QueryWrapper<InterfaceInfo> pageQueryWrapper = new QueryWrapper<>();
                // 2. 创建page对象传给wrapper对象执行
                Page<InterfaceInfo> page = interfaceInfoService.page(new Page<>(1, 10), pageQueryWrapper);
                // 3. 将数据存储到redis中
                // 4. 创建redisKey值
                String pageKey = PRESCHEDULER_NAME;

                System.out.println("开始执行！");

                // 5. 使用ops将值传入，并设置过期时间
                redisTemplate.opsForValue().set(pageKey, page, 3000, TimeUnit.SECONDS);

                Page<InterfaceInfo> interfaceInfoPage = (Page<InterfaceInfo>) redisTemplate.opsForValue().get(pageKey);
            }
        } catch (InterruptedException e) {
            log.error(e.getMessage());
        } finally {
            lock.unlock();
        }
    }
}
